#include <glib.h>

static void start( GMarkupParseContext *context, 
        const gchar *element_name, 
        const gchar **attribute_names, 
        const gchar **attribute_values, 
        gpointer user_data, 
        GError ** error ) 
{ 
    const gchar **name_cursor = attribute_names; 
    const gchar **value_cursor = attribute_values;

    g_printf("(start)element_name: %s \n", element_name);
    while (*name_cursor) {
        g_printf("(start)name_cursor:%s, value_cursor:%s \n", *name_cursor, *value_cursor);
        name_cursor++;
        value_cursor++;
    }
} 

static void end( GMarkupParseContext *context, 
        const gchar *element_name, 
        gpointer user_data, 
        GError **error ) 
{
    g_printf("(end)element_name: %s \n", element_name);
} 

static void text( GMarkupParseContext *context, 
        const gchar *text, 
        gsize text_len, 
        gpointer user_data, 
        GError **error ) 
{
    g_printf("(text)text:%s \n", text);
} 

static void err(GMarkupParseContext *context, 
        GError *error,
        gpointer user_data)
{
    g_print("(err)parse xml failed: %s \n", error->message);

}

GMarkupParser parser = { 
    . start_element = start, 
    . end_element = end, 
    . text = text, 
    . passthrough = NULL, 
    . error = err 
}; 

int main( ) 
{
    GMarkupParseContext *context; 

    gchar *buf = NULL;
    gsize length = 0;

    g_file_get_contents("xml_basic.xml" , &buf, &length, NULL); 
    g_print( "%s \n" , buf) ; 

    context = g_markup_parse_context_new(&parser, 0, NULL, NULL);
    if(NULL == context) {
        g_print("context new failed! \n");
        return -1;
    }

    if(FALSE == g_markup_parse_context_parse(context, buf, length, NULL)) {
        g_print("context parse failed! \n");
    }
    
    g_markup_parse_context_free(context);

    return 0;
}
